using System;
using System.Collections.Generic;
using System.Xml;

namespace DynamicConfigurationManager.ConfigMapAttributes
{
    internal class ConfigMapHandler
    {
        private readonly Dictionary<string, IConfigMapAttribute> _configMapAttributesList =
            new Dictionary<string, IConfigMapAttribute>( StringComparer.InvariantCultureIgnoreCase )
        {
            { "assemblyPath", new AssemblyPath() },
            { "assemblyPathRegEx", new AssemblyPathRegEx() },
            { "callingTypeFullnameRegEx", new CallingTypeFullnameRegEx() },
            { "commandLineArg", new CommandLineArgs() },
            { "configPathRegEx", new ConfigPathRegEx() },
            { "currentDirectory", new CurrentDirectory() },
            { "currentDirectoryRegEx", new CurrentDirectoryRegEx() },
            { "environmentVariable", new EnvironmentVariable() },
            { "executablePath", new ExecutablePath() },
            { "executablePathRegEx", new ExecutablePathRegEx() },
            { "hostname", new HostnameList() },
            { "hostnameList", new HostnameList() }, // HostnameList() handler is intentional: avoid huma error when folks add another host to the list
            { "hostnameRegEx", new HostnameRegEx() },
            { "sitePathRegEx", new SitePathRegEx() },
            { "registryValueRegEx", new RegistryValueRegEx() },
            { "updateLocation", new UpdateLocation() },
            { "webHostName", new WebHostName() },
            { "webServiceBinPath", new WebServiceBinPath() },
            { "webUrl", new WebUrl() },
            { "webUrlList", new WebUrlList() },
            { "webUrlRegEx", new WebUrlRegEx() }
        };

        public bool IsHandled( XmlNode configMap )
        {
            var rtnValue = false;

            // ConfigMap element can have multiple attributes
            if( configMap.Attributes != null )
            {
                foreach( XmlAttribute attrib in configMap.Attributes )
                {
                    // skip the name attribute; that's just informational
                    if( attrib.Name.Equals( "name", StringComparison.InvariantCultureIgnoreCase ) )
                    {
                        LogHelper.Append( "Evaluating: {0}", attrib.Value );
                        continue;
                    }

                    if( string.IsNullOrWhiteSpace( attrib.Value ) )
                    {
                        LogHelper.Append( "Empty value for handler {0}; so no match here", attrib.Name );
                        break;
                    }

                    IConfigMapAttribute cmd;
                    if( _configMapAttributesList.TryGetValue( attrib.Name, out cmd ) )
                    {
                        // Evaluate the command
                        LogHelper.Append( "Testing command handler {0}: attributes: {1}", attrib.Name, attrib.Value );
                        rtnValue = cmd.Execute( attrib.Value );
                        LogHelper.Append( "Returned: {0}", rtnValue );

                        // All configMap attributes must return true or the configMap is not a match
                        if( rtnValue == false )
                        {
                            break;
                        }
                    }
                }
            }
            return rtnValue;
        }
    }
}